﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Acl.DataCheck
{
    internal class GroupUniqueIncreaseValidator : ConstraintValidator
    {
        internal static string Parse(ConstraintItem constraint, StringBuilder log)
        {
            var tokens = ParseToken(constraint.Expression);

            if (tokens.Length == 0)
            {
                log.AppendLine($"GUI 表达式不允许为空: {constraint.TableName}.{constraint.ColumnName} | ‘ {constraint.Expression} ’.");
                return null;
            }
            else if (tokens.Length == 1)
            {
                return tokens[0];
            }
            else
            {
                log.AppendLine($"GUI 表达式格式错误，只允许一个token: {constraint.TableName}.{constraint.ColumnName} | ‘ {constraint.Expression} ’.");
                return null;
            }
        }

        public override void Validate(ValidationContext ctx)
        {
            Guard.NotNull(ctx, nameof(ctx));

            if (ctx.Current.Type != ConstraintType.GroupUniqueIncrease)
                throw new NotSupportedException($"{nameof(GroupUniqueIncreaseValidator)} 不支持 '{ctx.Current.Type}' ,出错相关信息:{ctx.Current} ");
            if (!ctx.Tables.Contains(ctx.Current.TableName))
                throw new NotSupportedException($"{ctx.Current.TableName} 表名不存在 ,出错相关信息:{ctx.Current} ");

            var table = ctx.Tables[ctx.Current.TableName];
            if (!table.Members.Contains(ctx.Current.ColumnName))
                throw new NotSupportedException($"{ctx.Current.TableName}.{ctx.Current.ColumnName} 列不存在 ,出错相关信息:{ctx.Current} ");

            Type columnType = table.Members[ctx.Current.ColumnName].Type;

            //解析表达式
            var groupColumnName = Parse(ctx.Current, ctx.Logger);
            ctx.Current.Passed = !string.IsNullOrWhiteSpace(groupColumnName);

            if (!table.Members.Contains(groupColumnName))
                throw new NotSupportedException($"{ctx.Current.TableName}.{groupColumnName} 列不存在 ,出错相关信息:{ctx.Current} ");

            if (ctx.Current.Passed)
            {
                var groups = new Dictionary<dynamic, List<dynamic>>();
                List<dynamic> lastValues = default;
                List<dynamic> values = default;

                dynamic groupKey = default;
                dynamic lastGroupKey = default;

                foreach (dynamic row in table)
                {
                    var columnValue = row[ctx.Current.ColumnName];

                    lastGroupKey = groupKey;
                    lastValues = values;

                    groupKey = row[groupColumnName];

                    if (groups.TryGetValue(groupKey, out values))
                    {
                        values.Add(columnValue);
                    }
                    else
                    {
                        if (lastValues != null && lastValues.Count > 0)
                        {
                            lastValues = lastValues.OrderBy(x => x).ToList();

                            var i = 0;
                            var lastValue = lastValues[i];

                            for (i = 1; i < lastValues.Count; i++)
                            {
                                if ((lastValues[i] - lastValue) != 1) //确保步长为1
                                {
                                    ctx.Current.Passed = false;
                                    ctx.Logger.AppendLine($"在{groupColumnName}={lastGroupKey}的组中，列{ctx.Current.ColumnName}的值[{string.Join(",", lastValues)}]不是有序递增的.");
                                    break;
                                }
                                lastValue = lastValues[i];
                            }
                        }
                        values = [columnValue];
                        groups.Add(groupKey, values);
                    }
                }
            }
        }
    }
}